﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace myDEM插值
{
    public partial class main : Form
    {
        #region main
        public main()
        {
            InitializeComponent();
        }
        #endregion

        #region inverse the matrix
        public static double[,] Inverse(double[,] Array)
        {
            int m = 0;
            int n = 0;
            m = Array.GetLength(0);
            n = Array.GetLength(1);
            double[,] array = new double[2 * m + 1, 2 * n + 1];
            for (int k = 0; k < 2 * m + 1; k++)  
            {
                for (int t = 0; t < 2 * n + 1; t++)
                {
                    array[k, t] = 0.00000000;
                }
            }
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    array[i, j] = Array[i, j];
                }
            }

            for (int k = 0; k < m; k++)
            {
                for (int t = n; t <= 2 * n; t++)
                {
                    if ((t - k) == m)
                    {
                        array[k, t] = 1.0;
                    }
                    else
                    {
                        array[k, t] = 0;
                    }
                }
            }
            for (int k = 0; k < m; k++)
            {
                if (array[k, k] != 1)
                {
                    double bs = array[k, k];
                    array[k, k] = 1;
                    for (int p = k + 1; p < 2 * n; p++)
                    {
                        array[k, p] /= bs;
                    }
                }
                for (int q = 0; q < m; q++)
                {
                    if (q != k)
                    {
                        double bs = array[q, k];
                        for (int p = 0; p < 2 * n; p++)
                        {
                            array[q, p] -= bs * array[k, p];
                        }
                    }
                    else
                    {
                        continue;
                    }
                }
            }
            double[,] NI = new double[m, n];
            for (int x = 0; x < m; x++)
            {
                for (int y = n; y < 2 * n; y++)
                {
                    NI[x, y - n] = array[x, y];
                }
            }
            return NI;
        }
        #endregion

        #region define the varibles
        PointF[] data = new PointF[10];//the original data
        double[] result = new double[6];//the answers
        #endregion

        #region open button
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            //initialization the interface
            this.Controls.Clear();
            InitializeComponent();

            // read the data
            openFileDialog1.Title = "open";
            openFileDialog1.Filter = "(*.txt)|*.txt";
            if(openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                StreamReader sr = new StreamReader(openFileDialog1.FileName);
                string line = sr.ReadLine();
                int i = 0;
                while(! sr.EndOfStream)
                {
                    line = sr.ReadLine();
                    dgv.Rows.Add();
                    string[] datas = line.Split('\t');       
                    for(int j = 0; j < datas.GetLength(0); j++)
                    {
                        dgv.Rows[i].Cells[j].Value = datas[j];
                    }
                    i++;
                }
                sr.Close();
            }

            //import data to variable
            for(int i=0; i<10; i++)
            {
                double X = Convert.ToDouble(dgv.Rows[i].Cells[1].Value);
                double Y = Convert.ToDouble(dgv.Rows[i].Cells[2].Value);
                double Z = Convert.ToDouble(dgv.Rows[i].Cells[3].Value);
                PointF p = new PointF(X - 110, Y - 110, Z);
                data[i] = p;
            }
        }


        #endregion

        #region calcuate button
        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            double[] L1 = new double[10];
            double[,] A = new double[10, 6];
            double[,] AT = new double[6, 10];
            for(int i=0; i<10; i++)
            {
                L1[i] = data[i].Z;

                A[i,0] = data[i].X * data[i].X;
                A[i,1] = data[i].X * data[i].Y;
                A[i,2] = data[i].Y * data[i].Y;
                A[i,3] = data[i].X;
                A[i,4] = data[i].Y;
                A[i,5] = 1;

                for (int j = 0; j < 6; j++)
                {
                    AT[j,i] = A[i,j];
                }
            }
            double t;
            double[,] ATA = new double[6, 6];
            for (int i = 0; i < 6; i++)
            {
                for (int m = 0; m < 6; m++)
                {
                    t = 0;
                    for (int j = 0; j < 10; j++)
                    {
                        t = AT[i,j] * A[j,m] + t;
                    }
                    ATA[i,m] = t;
                }
            }

            // inverse(ATA)
            ATA = Inverse(ATA);

            double[,] A1 = new double[6, 10];
            double tt;
            for (int i = 0; i < 6; i++)
            {
                for (int m = 0; m < 10; m++)
                {
                    tt = 0;
                    for (int j = 0; j < 6; j++)
                    {
                        tt = ATA[i,j] * AT[j,m] + tt;
                    }
                    A1[i,m] = tt;
                }
            }
            for (int i = 0; i < 6; i++)
            {
                double o = 0;
                for (int j = 0; j < 10; j++)
                {
                    o = A1[i,j] * L1[j] + o;
                }
                result[i] = o;
            }
            //MessageBox.Show(result[5].ToString());
            ansbox.Text = (
                string.Format("A:{0}, B:{1}, C:{2}, D:{3}, E:{4}, F:{5}", 
                Math.Round(result[0], 5), Math.Round(result[1], 5), Math.Round(result[2], 5), 
                Math.Round(result[3], 5), Math.Round(result[4], 5), Math.Round(result[5], 5)
                ));
        }

        #endregion

        #region save button
        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            saveFileDialog1.FileName = "save ans";
            saveFileDialog1.Filter = "(*.txt)|*.txt";
            if(saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                StreamWriter sw = new StreamWriter(saveFileDialog1.FileName);
                string ans = string.Format("A:{0}, B:{1}, C:{2}, D:{3}, E:{4}, F:{5}",
                result[0], result[1], result[2], result[3], result[4], result[5]);
                sw.Write(ans);
                sw.Close();
                MessageBox.Show("save successfully!");
            }
        }
        #endregion
    }
}
